package bank.server;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;

import bank.Bank;
import bank.InactiveException;
import bank.OverdrawException;
import bank.local.LocalAccount;
import bank.local.LocalBank;
import bank.transport.Answer;
import bank.transport.Request;

public class BankHandler implements Runnable {
	// client socket
	private ServerSocket socket;
	// streams
	private ObjectOutputStream out;
	private ObjectInputStream in;
	// bank of the server
	private LocalBank bank;

	/**
	 * Constructor.
	 * 
	 * @param bank The local bank used by the server.
	 * @param socket The socket to the client.
	 */
	public BankHandler(LocalBank bank, ServerSocket socket) {
		this.bank = bank;
		this.socket = socket;
	}

	public void run() {
		while(true) {
			Socket client = null;

			try {
				client = socket.accept();
				
				in = new ObjectInputStream(client.getInputStream());
				out = new ObjectOutputStream(client.getOutputStream());
				
				while(true){				
					Request r = (Request)in.readObject();

					Answer a = action(r);
					
					out.writeObject(a);	
					out.flush();
				}
						
			} catch (IOException e) {
			} catch (ClassNotFoundException e) {
			} catch (IllegalArgumentException e) {
				e.printStackTrace();
			} catch (InactiveException e) {
				e.printStackTrace();
			} catch (OverdrawException e) {
				e.printStackTrace();
			}
		}
	}


	// Take a request and do correponding action
	private Answer action(Request r) throws IOException, IllegalArgumentException, InactiveException, OverdrawException {
		if (r.str1.equals("createAccount")) {
			
			return new Answer(bank.createAccount(r.str2));
		} else if (r.str1.equals("removeAccount")){
			return new Answer(bank.removeAccount(r.str2));
		} else if (r.str1.equals("getAccountNumbers")){
			return new Answer(bank.getAccountNumbers());
		} else if (r.str1.equals("getAccount")){
			return new Answer(bank.getAccount(r.str2));
		} else if (r.str1.equals("transfer")){
			bank.transfer(r.acc1, r.acc2, r.dbl1);
		} else if (r.str1.equals("deposit")){
			bank.getAccount(r.str2).deposit(r.dbl1);
		} else if (r.str1.equals("withdraw")){
			bank.getAccount(r.str2).withdraw(r.dbl1);
		}
 
		return null;
	}
}
